import type { Ref } from 'vue'
import { getCurrentInstance, ref, toRef, unref, watch } from 'vue'

/** 使用 v-model */
export function useVModel<P extends object, K extends keyof P, Name extends string>(
  props: P,
  key: K,
  emit?: (name: Name, ...args: any[]) => void,
): Ref<P[K]> {
  const event = `update:${key as string}`
  const modelValue = toRef(props, key)
  const vm = getCurrentInstance()
  // @ts-expect-error mis-alignment with @vue/composition-api
  const _emit = emit || vm?.emit || vm?.$emit?.bind(vm)
  /** 组件内 v-model 绑定的值 */
  const bindValue = ref(modelValue.value)

  watch(
    modelValue,
    (newVal: P[K]) => {
      bindValue.value = unref(newVal)
    },
    { immediate: true },
  )

  watch(
    bindValue,
    (newVal) => {
      _emit(event, newVal)
    },
    { immediate: true },
  )

  return bindValue
}
